package com.cx.auth.impl;

import com.cx.auth.AuthConstant;
import com.cx.auth.UserTokenService;
import com.cx.common.utils.JsonUtils;
import com.cx.po.SysUser;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @Author:chenxiaoyi
 * @Date:2020/12/30 18:27
 */
@Service
@Slf4j
public class UserTokenServiceImpl implements UserTokenService<SysUser> {

    @Autowired
    private StringRedisTemplate redisTemplate;


    protected long tokenTtlSecs;

    @Value("${token.ttl}")
    public void setTokenTtl(Duration duration) {
        this.tokenTtlSecs = duration.getSeconds();
    }


    /**
     * 创建token时权限列表为     List<Long>             返回前端
     * 拦截器里security需要得是  List<GrantedAuthority>
     * @param userDetails
     * @return
     */
    @Override
    public String createAccessToken(SysUser userDetails) {
        String token = Jwts.builder().setId(UUID.randomUUID().toString().replaceAll("-",""))
                .claim(AuthConstant.AUTH_KEY, userDetails)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + tokenTtlSecs))
                .signWith(SignatureAlgorithm.HS256, AuthConstant.SIGNING_KEY)
                .compact();
        redisTemplate.opsForValue().set(token,userDetails.getId().toString(),tokenTtlSecs, TimeUnit.MINUTES);
        return token;
    }

    @Override
    public boolean verify(String accessToken) {
        return false;
    }


    @Override
    public SysUser loadUserDetails(String accessToken) {
        try {
            Claims cx = Jwts.parser().setSigningKey(AuthConstant.SIGNING_KEY)
                    .parseClaimsJws(accessToken)
                    .getBody();
            return JsonUtils.string2Object(JsonUtils.object2String(cx.get(AuthConstant.AUTH_KEY)), SysUser.class);
        }catch (Exception e){
            log.error("parser jwtToken--{} fail",accessToken);
        }
        return null;
    }

    /**
     * 结合redis+jwt做退除校验
     */
    @Override
    public void clear(String accessToken) {
        try {
            Claims cx = Jwts.parser().setSigningKey(AuthConstant.SIGNING_KEY)
                    .parseClaimsJws(accessToken)
                    .getBody();
            SysUser sysUser = JsonUtils.string2Object(JsonUtils.object2String(cx.get(AuthConstant.AUTH_KEY)), SysUser.class);
            if(sysUser != null ){
                //清空redis
                redisTemplate.delete(accessToken);
            }
        }catch (Exception e){
            log.error("clear jwtToken--{} fail",accessToken);
        }
    }
}
